<?php
/* 
    Name：FastPHP
    CopyRight: Mr.Fu 2019SR0832915
*/
namespace app\extend\weixin;
/*
    微信支付API接口插件
        ---- SendRedPack：发红包
        ---- H5Pay      ：微信H5支付
        ---- NativePay  ：微信二维码支付
        ---- JsApiPay   ：微信公众号/小程序支付
        ---- SendRedPack：微信发红包
        ---- Refund     ：微信支付退款
        ---- Rransfers  ：微信打款接口
*/
use \app\base\Common;
use \app\extend\weixin\Wxcommon;

class Wxpay extends Common
{
	//微信基本支付配置
	protected $WxPayConfig=array();
        
	protected function _initialize()
	{
    	//执行父类的构造方法
        parent::_initialize();
		
		$this->WxPayConfig=array(
			'APPID'=>$this->Config['wxpay_appid'],
			'MCHID'=>$this->Config['wxpay_mchid'],
			'KEY'=>$this->Config['wxpay_appsecret'],
			'SSLCERT_PATH'=>dirname(__FILE__).'/cert/apiclient_cert.pem',
	        'SSLKEY_PATH'=>dirname(__FILE__).'/cert/apiclient_key.pem',
	        'NOTIFY_URL'=>$this->Config['weburl'].'/Paynotify/Wxpay_Callback'
    	);
    }
    
	//微信H5支付统一下单
	public function H5Pay($oid,$amount,$body='微信H5支付')
	{
        $weburl=$this->Config['weburl'];
        $notify_url=$this->WxPayConfig['NOTIFY_URL'];
        $scene_info='{"h5_info":{"type": "wap","wap_url": "'.$weburl.'","wap_name": "'.$body.'"}}';
		$nonce_str=GetRandStr(32);                                  //创建随机码
		$URL='https://api.mch.weixin.qq.com/pay/unifiedorder';      //接口地址
		$order['appid']=$this->WxPayConfig['APPID'];                //应用ID
		$order['mch_id']=$this->WxPayConfig['MCHID'];               //商户号
		$order['device_info']='WEB';                                //设备号
		$order['nonce_str']=$nonce_str;                             //随机字符串
		$order['sign_type']='MD5';                                  //签名类型
		$order['body']=$body;                                       //商品描述
		$order['out_trade_no']=$oid;                                //商户订单号
		$order['total_fee']=$amount*100;                            //总金额
		$order['spbill_create_ip']=GetIP();                         //终端IP
		$order['time_start']=date("YmdHis");                        //交易起始时间
		$order['time_expire']=date("YmdHis", time() + 600);         //交易结束时间
		$order['notify_url']=$notify_url;                           //通知地址
        $order['trade_type']='MWEB';                                //交易类型
        $order['scene_info']=$scene_info;                           //交易场景信息
		$Sign_Data=$order;
		$sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);//生成签名数据
		$order['sign']=$sign;
		$xml=Wxcommon::ToXml($order);
		$result=Wxcommon::postXmlCurl($xml,$URL);                   //POST方法发送XML请求
        $result=XmlToArray($result);                               //把返回结果转换成数组
        if(!isset($result['prepay_id'])){
        	return $result['return_msg'];
        }
        $prepay_id=$result['prepay_id'];
        $trade_type=$result['MWEB'];
        WLog('WxPay_H5','请求：'.array2string($order));
        WLog('WxPay_H5','响应：'.array2string($result));
        if(isset($result['mweb_url'])){
			return $result['mweb_url'];
        }else{
            return $result['return_msg'];
        }
    }

    //微信二维码支付统一下单
    public function NativePay($oid,$amount,$body='微信扫码支付')
    {
        $weburl=$this->Config['weburl'];
        $notify_url=$this->WxPayConfig['NOTIFY_URL'];

		$nonce_str=GetRandStr(16);                                  //创建随机码
		$URL='https://api.mch.weixin.qq.com/pay/unifiedorder';      //接口地址
		$order['appid']=$this->WxPayConfig['APPID'];                //应用ID
		$order['mch_id']=$this->WxPayConfig['MCHID'];               //商户号
		$order['device_info']='WEB';                                //设备号
		$order['nonce_str']=$nonce_str;                             //随机字符串
		$order['sign_type']='MD5';                                  //签名类型
		$order['body']=$body;                                       //商品描述
		$order['out_trade_no']=$oid;                                //商户订单号
		$order['total_fee']=$amount*100;                            //总金额
		$order['spbill_create_ip']=GetIP();                         //终端IP
		$order['time_start']=(date("YmdHis"));                      //交易起始时间
		$order['time_expire']=(date("YmdHis", time() + 600));       //交易结束时间
		$order['notify_url']=$notify_url;
		$order['trade_type']='NATIVE';                              //交易类型
		$Sign_Data=$order;
		$sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);//生成签名数据
		$order['sign']=$sign;
		$xml=Wxcommon::ToXml($order);
		$result=Wxcommon::postXmlCurl($xml,$URL);
        $result=XmlToArray($result);
        
        WLog('WxPay_Native','请求：'.$this->WxPayConfig['KEY'].array2string($order));
        WLog('WxPay_Native','响应：'.array2string($result));
		
		return $result;
    }

	//微信公众号/小程序支付统一下单
	public function JsApiPay($oid,$amount,$openid,$body='微信公众号支付')
	{
        $weburl=$this->Config['weburl'];
        $notify_url=$this->WxPayConfig['NOTIFY_URL'];
		$nonce_str=GetRandStr(32);                                              //创建随机码
		$URL='https://api.mch.weixin.qq.com/pay/unifiedorder';                  //接口地址
		$order['appid']=$this->WxPayConfig['APPID'];                            //应用ID
		$order['mch_id']=$this->WxPayConfig['MCHID'];                           //商户号
		$order['device_info']='WEB';                                            //设备号
		$order['nonce_str']=$nonce_str;                                         //随机字符串
		$order['sign_type']='MD5';                                              //签名类型
		$order['body']=$body;                                                   //商品描述
		$order['out_trade_no']=$oid;                                            //商户订单号
		$order['total_fee']=$amount*100;                                        //总金额
		$order['spbill_create_ip']=GetIP();                                     //终端IP
		$order['time_start']=date("YmdHis");                                    //交易起始时间
		$order['time_expire']=date("YmdHis", time() + 600);                     //交易结束时间
		$order['notify_url']=$notify_url;                                       //通知地址
		$order['trade_type']='JSAPI';                                           //交易类型
      	$order['openid']=$openid;
		$Sign_Data=$order;
		$sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);     //生成签名数据
		$order['sign']=$sign;
		$xml=Wxcommon::ToXml($order);
		$result=Wxcommon::postXmlCurl($xml,$URL);
		$result=XmlToArray($result);
      	WLog('WxPay_JsApi','请求：'.array2string($order));
        WLog('WxPay_JsApi','响应：'.array2string($result));
		//开始公众号发起支付参数签名
		$nonce_str=GetRandStr(32);
		$arr['appId']=$this->WxPayConfig['APPID'];
		$arr['timeStamp']=''.time().'';
		$arr['nonceStr']=$nonce_str;
		if(!isset($result['prepay_id'])){
			return $result['return_msg'];
		}
		$arr['package']="prepay_id=".$result['prepay_id'];
		$arr['signType']="MD5";
		$sign=Wxcommon::MakeSign_MD5($arr,$this->WxPayConfig['KEY']);
		$arr['paySign']=$sign;
		WLog('WxPay_JsApi','JsApi发起参数：'.array2string($arr));
		return $arr;
    }
	//发红包创建请求订单
	public function SendRedPack($openid,$amount,$send_name,$wishing="恭喜发财",$act_name='红包活动')
	{
        $nonce_str=GetRandStr(32);                                              //创建随机码
      	$mch_billno=time().mt_rand(1000000,9999999);                            //创建订单号
        $URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';     //接口地址
        $order['wxappid']=$this->WxPayConfig['APPID'];                          //应用ID
        $order['mch_id']=$this->WxPayConfig['MCHID'];                           //商户号
        $order['nonce_str']=$nonce_str;                                         //随机字符串
      	$order['re_openid']=$openid;                                            //微信用户OPENID
      	$order['send_name']=$send_name;                                         //商户名称
      	$order['wishing']=$wishing;                                             //红包祝福语
      	$order['act_name']=$act_name;                                           //活动名称
      	$order['mch_billno']=$mch_billno;                                       //订单号
        $order['total_amount']=$amount*100;                                     //总金额
      	$order['total_num']=1;                                                  //红包人数
      	$order['client_ip']=GetIP();                                            //IP地址
        $Sign_Data=$order;                                                      //生成签名数据
        $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);     //签名
        $order['sign']=$sign;
        $xml=Wxcommon::ToXml($order);                                           //把参数转换成XML
      	$SSLCERT_PATH	=$this->WxPayConfig['SSLCERT_PATH'];
      	$SSLKEY_PATH	=$this->WxPayConfig['SSLKEY_PATH'];
        $result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH);    //POST方法发送XML请求
        $result=XmlToArray($result);                                           //把返回结果转换成数组
      	WLog('WxSendRedPack_Request_Api','请求：'.array2string($order));         //记录发红包请求、返回结果日志
      	WLog('WxSendRedPack_Request_Api','响应：'.array2string($result));
        return $result;
    }
	//微信支付退款
	public function Refund($transaction_id,$amount,$body='商品已售完')
	{
		$nonce_str=GetRandStr(32);                                              //创建随机码
      	$out_refund_no=time().mt_rand(1000000,9999999);                         //生成退款订单号
		$URL='https://api.mch.weixin.qq.com/secapi/pay/refund';                 //接口地址
		$order['appid']=$this->WxPayConfig['APPID'];                            //应用ID
		$order['mch_id']=$this->WxPayConfig['MCHID'];                           //商户号
		$order['nonce_str']=$nonce_str;                                         //随机字符串
		$order['sign_type']='MD5';                                              //签名类型
		$order['refund_desc']=$body;                                            //退款原因
		$order['transaction_id']=$transaction_id;                               //退款交易号
      	$order['out_refund_no']=$out_refund_no;                                 //商户退款单号 
		$order['total_fee']=$amount*100;                                        //总金额
      	$order['refund_fee']=$amount*100;                                       //退款金额
		$Sign_Data=$order;
		$sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);     //生成签名数据
		$order['sign']=$sign;
		$xml=Wxcommon::ToXml($order);
      	$SSLCERT_PATH	=$this->WxPayConfig['SSLCERT_PATH'];
      	$SSLKEY_PATH	=$this->WxPayConfig['SSLKEY_PATH'];
		$result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH);
		$result=XmlToArray($result);
      	WLog('WxRefund_Api','请求：'.array2string($order));
		WLog('WxRefund_Api','响应：'.array2string($result));
		return $result;
    }
	//微信打款接口
	public function Rransfers($partner_trade_no,$openid,$amount,$body='佣金打款')
	{
		$nonce_str=GetRandStr(32);                                                  //创建随机码
		$URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //接口地址
		$order['mch_appid']=$this->WxPayConfig['APPID'];                            //应用ID
		$order['mchid']=$this->WxPayConfig['MCHID'];                                //商户号
		$order['nonce_str']=$nonce_str;                                             //随机字符串
		$order['openid']=$openid;                                                   //用户openid
		$order['check_name']='NO_CHECK';                                            //校验用户姓名选项
		$order['desc']=$body;                                                       //打款原因
      	$order['partner_trade_no']=$partner_trade_no;                               //商户单号
		$order['amount']=$amount*100;                                               //总金额
		$order['spbill_create_ip']=GetIP();                                         //Ip地址
		$Sign_Data=$order;
		$sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);         //生成签名数据
		$order['sign']=$sign;
		$xml=Wxcommon::ToXml($order);
      	$SSLCERT_PATH	=$this->WxPayConfig['SSLCERT_PATH'];
      	$SSLKEY_PATH	=$this->WxPayConfig['SSLKEY_PATH'];      
		$result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH);
		$result=XmlToArray($result);
        WLog('WxRransfers_Api','请求：'.array2string($order));
		WLog('WxRransfers_Api','响应：'.array2string($result));        
		return $result;
    }
    //支付回调参数合法校验
  	public function Callback_SignCheck($order)
    {
      	$sign=$order['sign'];
      	unset($order['sign']);
    	$sign2=Wxcommon::MakeSign_MD5($order,$this->WxPayConfig['KEY']);
      	if($sign==$sign2){
        	return true;
        }else{
        	return false;
        }
    }
  	public function Return_Result($status,$msg)
    {
    	$data['return_code']=$status;
      	$data['return_msg']=$msg;
      	echo Wxcommon::ToXml($data);
    }
}
?>